home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MOR55SRC.ZIP / MORIA / SOURCE / GENERATE.ORI < prev    next >
Text File  |  1992-12-07  |  36KB  |  1,524 lines

  1. /* source/generate.c: initialize/create a dungeon or town level
  2.  
  3.    Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  4.  
  5.    This software may be copied and distributed for educational, research, and
  6.    not for profit purposes provided that this copyright and statement are
  7.    included in all such copies. */
  8.  
  9. #include "config.h"
  10. #include "constant.h"
  11. #include "types.h"
  12. #include "externs.h"
  13.  
  14. #if defined(USG) && !defined(VMS) && !defined(MAC)
  15. #if !defined(ATARIST_MWC) && !defined(AMIGA)
  16. #if !defined(__TURBOC__)
  17. #include <memory.h>
  18. #else
  19. #ifndef ATARIST_TC
  20. #include <mem.h>
  21. #endif
  22. #endif
  23. #endif
  24. #endif
  25.  
  26. #if defined(MAC)
  27. #include <string.h>
  28. #endif
  29.  
  30. #ifdef ATARIST_TC
  31. #include <string.h>
  32. #endif
  33.  
  34. typedef struct coords {
  35.   int x, y;
  36. } coords;
  37.  
  38. #if defined(LINT_ARGS)
  39. static void correct_dir(int *, int * , int, int, int, int);
  40. static void rand_dir(int *,int *);
  41. static void blank_cave(void);
  42. static void fill_cave(int);
  43. static void place_boundary(void);
  44. static void place_streamer(int, int);
  45. static void place_open_door(int, int);
  46. static void place_broken_door(int, int);
  47. static void place_closed_door(int, int);
  48. static void place_locked_door(int, int);
  49. static void place_stuck_door(int, int);
  50. static void place_secret_door(int, int);
  51. static void place_door(int, int);
  52. static void place_up_stairs(int, int);
  53. static void place_down_stairs(int, int);
  54. static void place_stairs(int, int, int);
  55. static void vault_trap(int, int, int, int, int);
  56. static void vault_monster(int, int, int);
  57. static void build_room(int, int);
  58. static void build_type1(int, int);
  59. static void build_type2(int, int);
  60. static void build_type3(int, int);
  61. static void build_tunnel(int, int, int, int);
  62. static int next_to(int, int);
  63. static void try_door(int, int);
  64. static void new_spot(int16 *, int16 *);
  65. static void cave_gen(void);
  66. static void build_store(int, int, int);
  67. static void tlink(void);
  68. static void mlink(void);
  69. static void town_gen(void);
  70. #endif
  71.  
  72. static coords doorstk[100];
  73. static int doorindex;
  74.  
  75.  
  76. /* Always picks a correct direction        */
  77. static void correct_dir(rdir, cdir, y1, x1, y2, x2)
  78. int *rdir, *cdir;
  79. register int y1, x1, y2, x2;
  80. {
  81.   if (y1 < y2)
  82.     *rdir =  1;
  83.   else if (y1 == y2)
  84.     *rdir =  0;
  85.   else
  86.     *rdir = -1;
  87.   if (x1 < x2)
  88.     *cdir =  1;
  89.   else if (x1 == x2)
  90.     *cdir =  0;
  91.   else
  92.     *cdir = -1;
  93.   if ((*rdir != 0) && (*cdir != 0))
  94.     {
  95.       if (randint (2) == 1)
  96.     *rdir = 0;
  97.       else
  98.     *cdir = 0;
  99.     }
  100. }
  101.  
  102.  
  103. /* Chance of wandering direction            */
  104. static void rand_dir(rdir, cdir)
  105. int *rdir, *cdir;
  106. {
  107.   register int tmp;
  108.  
  109.   tmp = randint(4);
  110.   if (tmp < 3)
  111.     {
  112.       *cdir = 0;
  113.       *rdir = -3 + (tmp << 1); /* tmp=1 -> *rdir=-1; tmp=2 -> *rdir=1 */
  114.     }
  115.   else
  116.     {
  117.       *rdir = 0;
  118.       *cdir = -7 + (tmp << 1); /* tmp=3 -> *cdir=-1; tmp=4 -> *cdir=1 */
  119.     }
  120. }
  121.  
  122.  
  123. /* Blanks out entire cave                -RAK-    */
  124. static void blank_cave()
  125. {
  126. #ifndef USG
  127.   bzero ((char *)&cave[0][0], sizeof (cave));
  128. #else
  129. #ifdef MAC
  130.   /* On the mac, cave is a pointer, so sizeof(cave) = 4! */
  131.   (void)memset((char *)&cave[0][0], 0,
  132.            (long) sizeof(cave_type) * MAX_HEIGHT * MAX_WIDTH);
  133. #else
  134.   (void)memset((char *)&cave[0][0], 0, sizeof (cave));
  135. #endif
  136. #endif
  137. }
  138.  
  139.  
  140. /* Fills in empty spots with desired rock        -RAK-    */
  141. /* Note: 9 is a temporary value.                */
  142. static void fill_cave(fval)
  143. register int fval;
  144. {
  145.   register int i, j;
  146.   register cave_type *c_ptr;
  147.  
  148.   /* no need to check the border of the cave */
  149.  
  150.   for (i = cur_height - 2; i > 0; i--)
  151.     {
  152.       c_ptr = &cave[i][1];
  153.       for (j = cur_width - 2; j > 0; j--)
  154.     {
  155.       if ((c_ptr->fval == NULL_WALL) || (c_ptr->fval == TMP1_WALL) ||
  156.           (c_ptr->fval == TMP2_WALL))
  157.         c_ptr->fval = fval;
  158.       c_ptr++;
  159.     }
  160.     }
  161. }
  162.  
  163. #ifdef DEBUG
  164. #include <assert.h>
  165. #endif
  166.  
  167. /* Places indestructible rock around edges of dungeon    -RAK-    */
  168. static void place_boundary()
  169. {
  170.   register int i;
  171.   register cave_type *top_ptr, *bottom_ptr;
  172.   cave_type (*left_ptr)[MAX_WIDTH];
  173.   cave_type (*right_ptr)[MAX_WIDTH];
  174.  
  175.   /* put permanent wall on leftmost row and rightmost row */
  176.   left_ptr = (cave_type (*)[MAX_WIDTH]) &cave[0][0];
  177.   right_ptr = (cave_type (*)[MAX_WIDTH]) &cave[0][cur_width - 1];
  178.  
  179.   for (i = 0; i < cur_height; i++)
  180.     {
  181. #ifdef DEBUG
  182.       assert ((cave_type *)left_ptr == &cave[i][0]);
  183.       assert ((cave_type *)right_ptr == &cave[i][cur_width-1]);
  184. #endif
  185.  
  186.       ((cave_type *)left_ptr)->fval    = BOUNDARY_WALL;
  187.       left_ptr++;
  188.       ((cave_type *)right_ptr)->fval    = BOUNDARY_WALL;
  189.       right_ptr++;
  190.     }
  191.  
  192.   /* put permanent wall on top row and bottom row */
  193.   top_ptr = &cave[0][0];
  194.   bottom_ptr = &cave[cur_height - 1][0];
  195.  
  196.   for (i = 0; i < cur_width; i++)
  197.     {
  198. #ifdef DEBUG
  199.       assert (top_ptr == &cave[0][i]);
  200.       assert (bottom_ptr == &cave[cur_height - 1][i]);
  201. #endif
  202.  
  203.       top_ptr->fval    = BOUNDARY_WALL;
  204.       top_ptr++;
  205.       bottom_ptr->fval    = BOUNDARY_WALL;
  206.       bottom_ptr++;
  207.     }
  208. }
  209.  
  210.  
  211. /* Places "streamers" of rock through dungeon        -RAK-    */
  212. static void place_streamer(fval, treas_chance)
  213. int fval;
  214. int treas_chance;
  215. {
  216.   register int i, tx, ty;
  217.   int y, x, t1, t2, dir;
  218.   register cave_type *c_ptr;
  219.  
  220.   /* Choose starting point and direction        */
  221.   y = (cur_height / 2) + 11 - randint(23);
  222.   x = (cur_width / 2)  + 16 - randint(33);
  223.  
  224.   dir = randint(8);    /* Number 1-4, 6-9    */
  225.   if (dir > 4)
  226.     dir = dir + 1;
  227.  
  228.   /* Place streamer into dungeon            */
  229.   t1 = 2*DUN_STR_RNG + 1;    /* Constants    */
  230.   t2 =     DUN_STR_RNG + 1;
  231.   do
  232.     {
  233.       for (i = 0; i < DUN_STR_DEN; i++)
  234.     {
  235.       ty = y + randint(t1) - t2;
  236.       tx = x + randint(t1) - t2;
  237.       if (in_bounds(ty, tx))
  238.         {
  239.           c_ptr = &cave[ty][tx];
  240.           if (c_ptr->fval == GRANITE_WALL)
  241.         {
  242.           c_ptr->fval = fval;
  243.           if (randint(treas_chance) == 1)
  244.             place_gold(ty, tx);
  245.         }
  246.         }
  247.     }
  248.     }
  249.   while (mmove(dir, &y, &x));
  250. }
  251.  
  252.  
  253. static void place_open_door(y, x)
  254. int y, x;
  255. {
  256.   register int cur_pos;
  257.   register cave_type *cave_ptr;
  258.  
  259.   cur_pos = popt();
  260.   cave_ptr = &cave[y][x];
  261.   cave_ptr->tptr = cur_pos;
  262.   invcopy(&t_list[cur_pos], OBJ_OPEN_DOOR);
  263.   cave_ptr->fval  = CORR_FLOOR;
  264. }
  265.  
  266.  
  267. static void place_broken_door(y, x)
  268. int y, x;
  269. {
  270.   register int cur_pos;
  271.   register cave_type *cave_ptr;
  272.  
  273.   cur_pos = popt();
  274.   cave_ptr = &cave[y][x];
  275.   cave_ptr->tptr = cur_pos;
  276.   invcopy(&t_list[cur_pos], OBJ_OPEN_DOOR);
  277.   cave_ptr->fval  = CORR_FLOOR;
  278.   t_list[cur_pos].p1 = 1;
  279. }
  280.  
  281.  
  282. static void place_closed_door(y, x)
  283. int y, x;
  284. {
  285.   register int cur_pos;
  286.   register cave_type *cave_ptr;
  287.  
  288.   cur_pos = popt();
  289.   cave_ptr = &cave[y][x];
  290.   cave_ptr->tptr = cur_pos;
  291.   invcopy(&t_list[cur_pos], OBJ_CLOSED_DOOR);
  292.   cave_ptr->fval  = BLOCKED_FLOOR;
  293. }
  294.  
  295.  
  296. static void place_locked_door(y, x)
  297. int y, x;
  298. {
  299.   register int cur_pos;
  300.   register cave_type *cave_ptr;
  301.  
  302.   cur_pos = popt();
  303.   cave_ptr = &cave[y][x];
  304.   cave_ptr->tptr = cur_pos;
  305.   invcopy(&t_list[cur_pos], OBJ_CLOSED_DOOR);
  306.   cave_ptr->fval  = BLOCKED_FLOOR;
  307.   t_list[cur_pos].p1 = randint(10) + 10;
  308. }
  309.  
  310.  
  311. static void place_stuck_door(y, x)
  312. int y, x;
  313. {
  314.   register int cur_pos;
  315.   register cave_type *cave_ptr;
  316.  
  317.   cur_pos = popt();
  318.   cave_ptr = &cave[y][x];
  319.   cave_ptr->tptr = cur_pos;
  320.   invcopy(&t_list[cur_pos], OBJ_CLOSED_DOOR);
  321.   cave_ptr->fval  = BLOCKED_FLOOR;
  322.   t_list[cur_pos].p1 = -randint(10) - 10;
  323. }
  324.  
  325.  
  326. static void place_secret_door(y, x)
  327. int y, x;
  328. {
  329.   register int cur_pos;
  330.   register cave_type *cave_ptr;
  331.  
  332.   cur_pos = popt();
  333.   cave_ptr = &cave[y][x];
  334.   cave_ptr->tptr = cur_pos;
  335.   invcopy(&t_list[cur_pos], OBJ_SECRET_DOOR);
  336.   cave_ptr->fval  = BLOCKED_FLOOR;
  337. }
  338.  
  339.  
  340. static void place_door(y, x)
  341. int y, x;
  342. {
  343.   register int tmp;
  344.  
  345.   tmp = randint(3);
  346.   if (tmp == 1)
  347.     {
  348.       if (randint(4) == 1)
  349.     place_broken_door(y, x);
  350.       else
  351.     place_open_door(y, x);
  352.     }
  353.   else if (tmp == 2)
  354.     {
  355.       tmp = randint(12);
  356.       if (tmp > 3)
  357.     place_closed_door(y, x);
  358.       else if (tmp == 3)
  359.     place_stuck_door(y, x);
  360.       else
  361.     place_locked_door(y, x);
  362.     }
  363.   else
  364.     place_secret_door(y, x);
  365. }
  366.  
  367.  
  368. /* Place an up staircase at given y, x            -RAK-    */
  369. static void place_up_stairs(y, x)
  370. int y, x;
  371. {
  372.   register int cur_pos;
  373.   register cave_type *cave_ptr;
  374.  
  375.   cave_ptr = &cave[y][x];
  376.   if (cave_ptr->tptr != 0)
  377.     (void) delete_object(y, x);
  378.   cur_pos = popt();
  379.   cave_ptr->tptr = cur_pos;
  380.   invcopy(&t_list[cur_pos], OBJ_UP_STAIR);
  381. }
  382.  
  383.  
  384. /* Place a down staircase at given y, x            -RAK-    */
  385. static void place_down_stairs(y, x)
  386. int y, x;
  387. {
  388.   register int cur_pos;
  389.   register cave_type *cave_ptr;
  390.  
  391.   cave_ptr = &cave[y][x];
  392.   if (cave_ptr->tptr != 0)
  393.     (void) delete_object(y, x);
  394.   cur_pos = popt();
  395.   cave_ptr->tptr = cur_pos;
  396.   invcopy(&t_list[cur_pos], OBJ_DOWN_STAIR);
  397. }
  398.  
  399.  
  400. /* Places a staircase 1=up, 2=down            -RAK-    */
  401. static void place_stairs(typ, num, walls)
  402. int typ, num, walls;
  403. {
  404.   register cave_type *cave_ptr;
  405.   int i, j, flag;
  406.   register int y1, x1, y2, x2;
  407.  
  408.   for (i = 0; i < num; i++)
  409.     {
  410.       flag = FALSE;
  411.       do
  412.     {
  413.       j = 0;
  414.       do
  415.         {
  416.           /* Note: don't let y1/x1 be zero, and don't let y2/x2 be equal
  417.          to cur_height-1/cur_width-1, these values are always
  418.          BOUNDARY_ROCK. */
  419.           y1 = randint(cur_height - 14);
  420.           x1 = randint(cur_width  - 14);
  421.           y2 = y1 + 12;
  422.           x2 = x1 + 12;
  423.           do
  424.         {
  425.           do
  426.             {
  427.               cave_ptr = &cave[y1][x1];
  428.               if (cave_ptr->fval <= MAX_OPEN_SPACE
  429.               && (cave_ptr->tptr == 0)
  430.               && (next_to_walls(y1, x1) >= walls))
  431.             {
  432.               flag = TRUE;
  433.               if (typ == 1)
  434.                 place_up_stairs(y1, x1);
  435.               else
  436.                 place_down_stairs(y1, x1);
  437.             }
  438.               x1++;
  439.             }
  440.           while ((x1 != x2) && (!flag));
  441.           x1 = x2 - 12;
  442.           y1++;
  443.         }
  444.           while ((y1 != y2) && (!flag));
  445.           j++;
  446.         }
  447.       while ((!flag) && (j <= 30));
  448.       walls--;
  449.     }
  450.       while (!flag);
  451.     }
  452. }
  453.  
  454.  
  455. /* Place a trap with a given displacement of point    -RAK-    */
  456. static void vault_trap(y, x, yd, xd, num)
  457. int y, x, yd, xd, num;
  458. {
  459.   register int count, y1, x1;
  460.   int i, flag;
  461.   register cave_type *c_ptr;
  462.  
  463.   for (i = 0; i < num; i++)
  464.     {
  465.       flag = FALSE;
  466.       count = 0;
  467.       do
  468.     {
  469.       y1 = y - yd - 1 + randint(2*yd+1);
  470.       x1 = x - xd - 1 + randint(2*xd+1);
  471.       c_ptr = &cave[y1][x1];
  472.       if ((c_ptr->fval != NULL_WALL) && (c_ptr->fval <= MAX_CAVE_FLOOR)
  473.           && (c_ptr->tptr == 0))
  474.         {
  475.           place_trap(y1, x1, randint(MAX_TRAP)-1);
  476.           flag = TRUE;
  477.         }
  478.       count++;
  479.     }
  480.       while ((!flag) && (count <= 5));
  481.     }
  482. }
  483.  
  484.  
  485. /* Place a trap with a given displacement of point    -RAK-    */
  486. static void vault_monster(y, x, num)
  487. int y, x, num;
  488. {
  489.   register int i;
  490.   int y1, x1;
  491.  
  492.   for (i = 0; i < num; i++)
  493.     {
  494.       y1 = y;
  495.       x1 = x;
  496.       (void) summon_monster(&y1, &x1, TRUE);
  497.     }
  498. }
  499.  
  500.  
  501. /* Builds a room at a row, column coordinate        -RAK-    */
  502. static void build_room(yval, xval)
  503. int yval, xval;
  504. {
  505.   register int i, j, y_depth, x_right;
  506.   int y_height, x_left;
  507.   int8u floor;
  508.   register cave_type *c_ptr, *d_ptr;
  509.  
  510.   if (dun_level <= randint(25))
  511.     floor = LIGHT_FLOOR;    /* Floor with light    */
  512.   else
  513.     floor = DARK_FLOOR;        /* Dark floor        */
  514.  
  515.   y_height = yval - randint(4);
  516.   y_depth  = yval + randint(3);
  517.   x_left   = xval - randint(11);
  518.   x_right  = xval + randint(11);
  519.  
  520.   /* the x dim of rooms tends to be much larger than the y dim, so don't
  521.      bother rewriting the y loop */
  522.  
  523.   for (i = y_height; i <= y_depth; i++)
  524.     {
  525.       c_ptr = &cave[i][x_left];
  526.       for (j = x_left; j <= x_right; j++)
  527.     {
  528.       c_ptr->fval  = floor;
  529.       c_ptr->lr = TRUE;
  530.       c_ptr++;
  531.     }
  532.     }
  533.  
  534.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  535.     {
  536.       c_ptr = &cave[i][x_left-1];
  537.       c_ptr->fval   = GRANITE_WALL;
  538.       c_ptr->lr = TRUE;
  539.       c_ptr = &cave[i][x_right+1];
  540.       c_ptr->fval  = GRANITE_WALL;
  541.       c_ptr->lr = TRUE;
  542.     }
  543.  
  544.   c_ptr = &cave[y_height - 1][x_left];
  545.   d_ptr = &cave[y_depth + 1][x_left];
  546.   for (i = x_left; i <= x_right; i++)
  547.     {
  548.       c_ptr->fval  = GRANITE_WALL;
  549.       c_ptr->lr = TRUE;
  550.       c_ptr++;
  551.       d_ptr->fval   = GRANITE_WALL;
  552.       d_ptr->lr = TRUE;
  553.       d_ptr++;
  554.     }
  555. }
  556.  
  557.  
  558. /* Builds a room at a row, column coordinate        -RAK-    */
  559. /* Type 1 unusual rooms are several overlapping rectangular ones    */
  560. static void build_type1(yval, xval)
  561. int yval, xval;
  562. {
  563.   int y_height, y_depth;
  564.   int x_left, x_right, limit;
  565.   register int i0, i, j;
  566.   int8u floor;
  567.   register cave_type *c_ptr, *d_ptr;
  568.  
  569.   if (dun_level <= randint(25))
  570.     floor = LIGHT_FLOOR;    /* Floor with light    */
  571.   else
  572.     floor = DARK_FLOOR;        /* Dark floor        */
  573.   limit = 1 + randint(2);
  574.   for (i0 = 0; i0 < limit; i0++)
  575.     {
  576.       y_height = yval - randint(4);
  577.       y_depth  = yval + randint(3);
  578.       x_left   = xval - randint(11);
  579.       x_right  = xval + randint(11);
  580.  
  581.       /* the x dim of rooms tends to be much larger than the y dim, so don't
  582.      bother rewriting the y loop */
  583.  
  584.       for (i = y_height; i <= y_depth; i++)
  585.     {
  586.       c_ptr = &cave[i][x_left];
  587.       for (j = x_left; j <= x_right; j++)
  588.         {
  589.           c_ptr->fval  = floor;
  590.           c_ptr->lr = TRUE;
  591.           c_ptr++;
  592.         }
  593.     }
  594.       for (i = (y_height - 1); i <= (y_depth + 1); i++)
  595.     {
  596.       c_ptr = &cave[i][x_left-1];
  597.       if (c_ptr->fval != floor)
  598.         {
  599.           c_ptr->fval  = GRANITE_WALL;
  600.           c_ptr->lr = TRUE;
  601.         }
  602.       c_ptr = &cave[i][x_right+1];
  603.       if (c_ptr->fval != floor)
  604.         {
  605.           c_ptr->fval  = GRANITE_WALL;
  606.           c_ptr->lr = TRUE;
  607.         }
  608.     }
  609.       c_ptr = &cave[y_height - 1][x_left];
  610.       d_ptr = &cave[y_depth + 1][x_left];
  611.       for (i = x_left; i <= x_right; i++)
  612.     {
  613.       if (c_ptr->fval != floor)
  614.         {
  615.           c_ptr->fval  = GRANITE_WALL;
  616.           c_ptr->lr = TRUE;
  617.         }
  618.       c_ptr++;
  619.       if (d_ptr->fval != floor)
  620.         {
  621.           d_ptr->fval  = GRANITE_WALL;
  622.           d_ptr->lr = TRUE;
  623.         }
  624.       d_ptr++;
  625.     }
  626.     }
  627. }
  628.  
  629.  
  630. /* Builds an unusual room at a row, column coordinate    -RAK-    */
  631. /* Type 2 unusual rooms all have an inner room:            */
  632. /*   1 - Just an inner room with one door            */
  633. /*   2 - An inner room within an inner room            */
  634. /*   3 - An inner room with pillar(s)                */
  635. /*   4 - Inner room has a maze                    */
  636. /*   5 - A set of four inner rooms                */
  637. static void build_type2(yval, xval)
  638. int yval, xval;
  639. {
  640.   register int i, j, y_height, x_left;
  641.   int y_depth, x_right, tmp;
  642.   int8u floor;
  643.   register cave_type *c_ptr, *d_ptr;
  644.  
  645.   if (dun_level <= randint(25))
  646.     floor = LIGHT_FLOOR;    /* Floor with light    */
  647.   else
  648.     floor = DARK_FLOOR;        /* Dark floor        */
  649.   y_height = yval - 4;
  650.   y_depth  = yval + 4;
  651.   x_left   = xval - 11;
  652.   x_right  = xval + 11;
  653.  
  654.   /* the x dim of rooms tends to be much larger than the y dim, so don't
  655.      bother rewriting the y loop */
  656.  
  657.   for (i = y_height; i <= y_depth; i++)
  658.     {
  659.       c_ptr = &cave[i][x_left];
  660.       for (j = x_left; j <= x_right; j++)
  661.     {
  662.       c_ptr->fval  = floor;
  663.       c_ptr->lr = TRUE;
  664.       c_ptr++;
  665.     }
  666.     }
  667.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  668.     {
  669.       c_ptr = &cave[i][x_left-1];
  670.       c_ptr->fval   = GRANITE_WALL;
  671.       c_ptr->lr = TRUE;
  672.       c_ptr = &cave[i][x_right+1];
  673.       c_ptr->fval  = GRANITE_WALL;
  674.       c_ptr->lr = TRUE;
  675.     }
  676.   c_ptr = &cave[y_height - 1][x_left];
  677.   d_ptr = &cave[y_depth + 1][x_left];
  678.   for (i = x_left; i <= x_right; i++)
  679.     {
  680.       c_ptr->fval  = GRANITE_WALL;
  681.       c_ptr->lr = TRUE;
  682.       c_ptr++;
  683.       d_ptr->fval   = GRANITE_WALL;
  684.       d_ptr->lr = TRUE;
  685.       d_ptr++;
  686.     }
  687.   /* The inner room        */
  688.   y_height = y_height + 2;
  689.   y_depth  = y_depth  - 2;
  690.   x_left   = x_left   + 2;
  691.   x_right  = x_right  - 2;
  692.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  693.     {
  694.       cave[i][x_left-1].fval = TMP1_WALL;
  695.       cave[i][x_right+1].fval = TMP1_WALL;
  696.     }
  697.   c_ptr = &cave[y_height-1][x_left];
  698.   d_ptr = &cave[y_depth+1][x_left];
  699.   for (i = x_left; i <= x_right; i++)
  700.     {
  701.       c_ptr->fval = TMP1_WALL;
  702.       c_ptr++;
  703.       d_ptr->fval = TMP1_WALL;
  704.       d_ptr++;
  705.     }
  706.   /* Inner room variations        */
  707.   switch(randint(5))
  708.     {
  709.     case 1:    /* Just an inner room.    */
  710.       tmp = randint(4);
  711.       if (tmp < 3) {    /* Place a door    */
  712.     if (tmp == 1) place_secret_door(y_height-1, xval);
  713.     else          place_secret_door(y_depth+1, xval);
  714.       } else {
  715.     if (tmp == 3) place_secret_door(yval, x_left-1);
  716.     else          place_secret_door(yval, x_right+1);
  717.       }
  718.       vault_monster(yval, xval, 1);
  719.       break;
  720.  
  721.     case 2:    /* Treasure Vault    */
  722.       tmp = randint(4);
  723.       if (tmp < 3) {    /* Place a door    */
  724.     if (tmp == 1) place_secret_door(y_height-1, xval);
  725.     else          place_secret_door(y_depth+1, xval);
  726.       } else {
  727.     if (tmp == 3) place_secret_door(yval, x_left-1);
  728.     else          place_secret_door(yval, x_right+1);
  729.       }
  730.  
  731.       for (i = yval-1; i <= yval+1; i++)
  732.     {
  733.       cave[i][xval-1].fval     = TMP1_WALL;
  734.       cave[i][xval+1].fval     = TMP1_WALL;
  735.     }
  736.       cave[yval-1][xval].fval  = TMP1_WALL;
  737.       cave[yval+1][xval].fval  = TMP1_WALL;
  738.  
  739.       tmp = randint(4);    /* Place a door    */
  740.       if (tmp < 3)
  741.     place_locked_door(yval-3+(tmp<<1), xval); /* 1 -> yval-1; 2 -> yval+1*/
  742.       else
  743.     place_locked_door(yval, xval-7+(tmp<<1));
  744.  
  745.       /* Place an object in the treasure vault    */
  746.       tmp = randint(10);
  747.       if (tmp > 2)
  748.     place_object(yval, xval);
  749.       else if (tmp == 2)
  750.     place_down_stairs(yval, xval);
  751.       else
  752.     place_up_stairs(yval, xval);
  753.  
  754.       /* Guard the treasure well        */
  755.       vault_monster(yval, xval, 2+randint(3));
  756.       /* If the monsters don't get 'em.    */
  757.       vault_trap(yval, xval, 4, 10, 2+randint(3));
  758.       break;
  759.  
  760.     case 3:    /* Inner pillar(s).    */
  761.       tmp = randint(4);
  762.       if (tmp < 3) {    /* Place a door    */
  763.     if (tmp == 1) place_secret_door(y_height-1, xval);
  764.     else          place_secret_door(y_depth+1, xval);
  765.       } else {
  766.     if (tmp == 3) place_secret_door(yval, x_left-1);
  767.     else          place_secret_door(yval, x_right+1);
  768.       }
  769.  
  770.       for (i = yval-1; i <= yval+1; i++)
  771.     {
  772.       c_ptr = &cave[i][xval-1];
  773.       for (j = xval-1; j <= xval+1; j++)
  774.         {
  775.           c_ptr->fval = TMP1_WALL;
  776.           c_ptr++;
  777.         }
  778.     }
  779.       if (randint(2) == 1)
  780.     {
  781.       tmp = randint(2);
  782.       for (i = yval-1; i <= yval+1; i++)
  783.         {
  784.           c_ptr = &cave[i][xval-5-tmp];
  785.           for (j = xval-5-tmp; j <= xval-3-tmp; j++)
  786.         {
  787.           c_ptr->fval = TMP1_WALL;
  788.           c_ptr++;
  789.         }
  790.         }
  791.       for (i = yval-1; i <= yval+1; i++)
  792.         {
  793.           c_ptr = &cave[i][xval+3+tmp];
  794.           for (j = xval+3+tmp; j <= xval+5+tmp; j++)
  795.         {
  796.           c_ptr->fval  = TMP1_WALL;
  797.           c_ptr++;
  798.         }
  799.         }
  800.     }
  801.  
  802.       if (randint(3) == 1)    /* Inner rooms    */
  803.     {
  804.       c_ptr = &cave[yval-1][xval-5];
  805.       d_ptr = &cave[yval+1][xval-5];
  806.       for (i = xval-5; i <= xval+5; i++)
  807.         {
  808.           c_ptr->fval  = TMP1_WALL;
  809.           c_ptr++;
  810.           d_ptr->fval  = TMP1_WALL;
  811.           d_ptr++;
  812.         }
  813.       cave[yval][xval-5].fval = TMP1_WALL;
  814.       cave[yval][xval+5].fval = TMP1_WALL;
  815.       place_secret_door(yval-3+(randint(2)<<1), xval-3);
  816.       place_secret_door(yval-3+(randint(2)<<1), xval+3);
  817.       if (randint(3) == 1)    place_object(yval, xval-2);
  818.       if (randint(3) == 1)    place_object(yval, xval+2);
  819.       vault_monster(yval, xval-2, randint(2));
  820.       vault_monster(yval, xval+2, randint(2));
  821.     }
  822.       break;
  823.  
  824.     case 4:    /* Maze inside.    */
  825.       tmp = randint(4);
  826.       if (tmp < 3) {    /* Place a door    */
  827.     if (tmp == 1) place_secret_door(y_height-1, xval);
  828.     else          place_secret_door(y_depth+1, xval);
  829.       } else {
  830.     if (tmp == 3) place_secret_door(yval, x_left-1);
  831.     else          place_secret_door(yval, x_right+1);
  832.       }
  833.  
  834.       for (i = y_height; i <= y_depth; i++)
  835.     for (j = x_left; j <= x_right; j++)
  836.       if (0x1 & (j+i))
  837.         cave[i][j].fval = TMP1_WALL;
  838.  
  839.       /* Monsters just love mazes.        */
  840.       vault_monster(yval, xval-5, randint(3));
  841.       vault_monster(yval, xval+5, randint(3));
  842.       /* Traps make them entertaining.    */
  843.       vault_trap(yval, xval-3, 2, 8, randint(3));
  844.       vault_trap(yval, xval+3, 2, 8, randint(3));
  845.       /* Mazes should have some treasure too..    */
  846.       for (i = 0; i < 3; i++)
  847.     random_object(yval, xval, 1);
  848.       break;
  849.  
  850.     case 5:    /* Four small rooms.    */
  851.       for (i = y_height; i <= y_depth; i++)
  852.     cave[i][xval].fval = TMP1_WALL;
  853.  
  854.       c_ptr = &cave[yval][x_left];
  855.       for (i = x_left; i <= x_right; i++)
  856.     {
  857.       c_ptr->fval = TMP1_WALL;
  858.       c_ptr++;
  859.     }
  860.  
  861.       if (randint(2) == 1)
  862.     {
  863.       i = randint(10);
  864.       place_secret_door(y_height-1, xval-i);
  865.       place_secret_door(y_height-1, xval+i);
  866.       place_secret_door(y_depth+1, xval-i);
  867.       place_secret_door(y_depth+1, xval+i);
  868.     }
  869.       else
  870.     {
  871.       i = randint(3);
  872.       place_secret_door(yval+i, x_left-1);
  873.       place_secret_door(yval-i, x_left-1);
  874.       place_secret_door(yval+i, x_right+1);
  875.       place_secret_door(yval-i, x_right+1);
  876.     }
  877.  
  878.       /* Treasure in each one.        */
  879.       random_object(yval, xval, 2+randint(2));
  880.       /* Gotta have some monsters.        */
  881.       vault_monster(yval+2, xval-4, randint(2));
  882.       vault_monster(yval+2, xval+4, randint(2));
  883.       vault_monster(yval-2, xval-4, randint(2));
  884.       vault_monster(yval-2, xval+4, randint(2));
  885.       break;
  886.     }
  887. }
  888.  
  889.  
  890. /* Builds a room at a row, column coordinate        -RAK-    */
  891. /* Type 3 unusual rooms are cross shaped                */
  892. static void build_type3(yval, xval)
  893. int yval, xval;
  894. {
  895.   int y_height, y_depth;
  896.   int x_left, x_right;
  897.   register int tmp, i, j;
  898.   int8u floor;
  899.   register cave_type *c_ptr;
  900.  
  901.   if (dun_level <= randint(25))
  902.     floor = LIGHT_FLOOR;    /* Floor with light    */
  903.   else
  904.     floor = DARK_FLOOR;        /* Dark floor        */
  905.   tmp = 2 + randint(2);
  906.   y_height = yval - tmp;
  907.   y_depth  = yval + tmp;
  908.   x_left   = xval - 1;
  909.   x_right  = xval + 1;
  910.   for (i = y_height; i <= y_depth; i++)
  911.     for (j = x_left; j <= x_right; j++)
  912.       {
  913.     c_ptr = &cave[i][j];
  914.     c_ptr->fval = floor;
  915.     c_ptr->lr = TRUE;
  916.       }
  917.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  918.     {
  919.       c_ptr = &cave[i][x_left-1];
  920.       c_ptr->fval  = GRANITE_WALL;
  921.       c_ptr->lr = TRUE;
  922.       c_ptr = &cave[i][x_right+1];
  923.       c_ptr->fval  = GRANITE_WALL;
  924.       c_ptr->lr = TRUE;
  925.     }
  926.   for (i = x_left; i <= x_right; i++)
  927.     {
  928.       c_ptr = &cave[y_height-1][i];
  929.       c_ptr->fval  = GRANITE_WALL;
  930.       c_ptr->lr = TRUE;
  931.       c_ptr = &cave[y_depth+1][i];
  932.       c_ptr->fval  = GRANITE_WALL;
  933.       c_ptr->lr = TRUE;
  934.     }
  935.   tmp = 2 + randint(9);
  936.   y_height = yval - 1;
  937.   y_depth  = yval + 1;
  938.   x_left   = xval - tmp;
  939.   x_right  = xval + tmp;
  940.   for (i = y_height; i <= y_depth; i++)
  941.     for (j = x_left; j <= x_right; j++)
  942.       {
  943.     c_ptr = &cave[i][j];
  944.     c_ptr->fval = floor;
  945.     c_ptr->lr = TRUE;
  946.       }
  947.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  948.     {
  949.       c_ptr = &cave[i][x_left-1];
  950.       if (c_ptr->fval != floor)
  951.     {
  952.       c_ptr->fval  = GRANITE_WALL;
  953.       c_ptr->lr = TRUE;
  954.     }
  955.       c_ptr = &cave[i][x_right+1];
  956.       if (c_ptr->fval != floor)
  957.     {
  958.       c_ptr->fval  = GRANITE_WALL;
  959.       c_ptr->lr = TRUE;
  960.     }
  961.     }
  962.   for (i = x_left; i <= x_right; i++)
  963.     {
  964.       c_ptr = &cave[y_height-1][i];
  965.       if (c_ptr->fval != floor)
  966.     {
  967.       c_ptr->fval  = GRANITE_WALL;
  968.       c_ptr->lr = TRUE;
  969.     }
  970.       c_ptr = &cave[y_depth+1][i];
  971.       if (c_ptr->fval != floor)
  972.     {
  973.       c_ptr->fval  = GRANITE_WALL;
  974.       c_ptr->lr = TRUE;
  975.     }
  976.     }
  977.   /* Special features.            */
  978.   switch(randint(4))
  979.     {
  980.     case 1:    /* Large middle pillar        */
  981.       for (i = yval-1; i <= yval+1; i++)
  982.     {
  983.       c_ptr = &cave[i][xval-1];
  984.       for (j = xval-1; j <= xval+1; j++)
  985.         {
  986.           c_ptr->fval = TMP1_WALL;
  987.           c_ptr++;
  988.         }
  989.     }
  990.       break;
  991.  
  992.     case 2:    /* Inner treasure vault        */
  993.       for (i = yval-1; i <= yval+1; i++)
  994.     {
  995.       cave[i][xval-1].fval     = TMP1_WALL;
  996.       cave[i][xval+1].fval     = TMP1_WALL;
  997.     }
  998.       cave[yval-1][xval].fval  = TMP1_WALL;
  999.       cave[yval+1][xval].fval  = TMP1_WALL;
  1000.  
  1001.       tmp = randint(4);    /* Place a door    */
  1002.       if (tmp < 3)
  1003.     place_secret_door(yval-3+(tmp<<1), xval);
  1004.       else
  1005.     place_secret_door(yval, xval-7+(tmp<<1));
  1006.  
  1007.       /* Place a treasure in the vault        */
  1008.       place_object(yval, xval);
  1009.       /* Let's guard the treasure well.    */
  1010.       vault_monster(yval, xval, 2+randint(2));
  1011.       /* Traps naturally            */
  1012.       vault_trap(yval, xval, 4, 4, 1+randint(3));
  1013.       break;
  1014.  
  1015.     case 3:
  1016.       if (randint(3) == 1)
  1017.     {
  1018.       cave[yval-1][xval-2].fval = TMP1_WALL;
  1019.       cave[yval+1][xval-2].fval = TMP1_WALL;
  1020.       cave[yval-1][xval+2].fval = TMP1_WALL;
  1021.       cave[yval+1][xval+2].fval = TMP1_WALL;
  1022.       cave[yval-2][xval-1].fval = TMP1_WALL;
  1023.       cave[yval-2][xval+1].fval = TMP1_WALL;
  1024.       cave[yval+2][xval-1].fval = TMP1_WALL;
  1025.       cave[yval+2][xval+1].fval = TMP1_WALL;
  1026.       if (randint(3) == 1)
  1027.         {
  1028.           place_secret_door(yval, xval-2);
  1029.           place_secret_door(yval, xval+2);
  1030.           place_secret_door(yval-2, xval);
  1031.           place_secret_door(yval+2, xval);
  1032.         }
  1033.     }
  1034.       else if (randint(3) == 1)
  1035.     {
  1036.       cave[yval][xval].fval = TMP1_WALL;
  1037.       cave[yval-1][xval].fval = TMP1_WALL;
  1038.       cave[yval+1][xval].fval = TMP1_WALL;
  1039.       cave[yval][xval-1].fval = TMP1_WALL;
  1040.       cave[yval][xval+1].fval = TMP1_WALL;
  1041.     }
  1042.       else if (randint(3) == 1)
  1043.     cave[yval][xval].fval = TMP1_WALL;
  1044.       break;
  1045.  
  1046.     case 4:
  1047.       break;
  1048.     }
  1049. }
  1050.  
  1051.  
  1052. /* Constructs a tunnel between two points        */
  1053. static void build_tunnel(row1, col1, row2, col2)
  1054. int row1, col1, row2, col2;
  1055. {
  1056.   register int tmp_row, tmp_col, i, j;
  1057.   register cave_type *c_ptr;
  1058.   cave_type *d_ptr;
  1059.   coords tunstk[1000], wallstk[1000];
  1060.   coords *tun_ptr;
  1061.   int row_dir, col_dir, tunindex, wallindex;
  1062.   int stop_flag, door_flag, main_loop_count;
  1063.   int start_row, start_col;
  1064.  
  1065.   /* Main procedure for Tunnel            */
  1066.   /* Note: 9 is a temporary value        */
  1067.   stop_flag = FALSE;
  1068.   door_flag = FALSE;
  1069.   tunindex    = 0;
  1070.   wallindex   = 0;
  1071.   main_loop_count = 0;
  1072.   start_row = row1;
  1073.   start_col = col1;
  1074.   correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
  1075.  
  1076.   do
  1077.     {
  1078.       /* prevent infinite loops, just in case */
  1079.       main_loop_count++;
  1080.       if (main_loop_count > 2000)
  1081.     stop_flag = TRUE;
  1082.  
  1083.       if (randint(100) > DUN_TUN_CHG)
  1084.     {
  1085.       if (randint(DUN_TUN_RND) == 1)
  1086.         rand_dir(&row_dir, &col_dir);
  1087.       else
  1088.         correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
  1089.     }
  1090.       tmp_row = row1 + row_dir;
  1091.       tmp_col = col1 + col_dir;
  1092.       while (!in_bounds(tmp_row, tmp_col))
  1093.     {
  1094.       if (randint(DUN_TUN_RND) == 1)
  1095.         rand_dir(&row_dir, &col_dir);
  1096.       else
  1097.         correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
  1098.       tmp_row = row1 + row_dir;
  1099.       tmp_col = col1 + col_dir;
  1100.     }
  1101.       c_ptr = &cave[tmp_row][tmp_col];
  1102.       if (c_ptr->fval == NULL_WALL)
  1103.     {
  1104.       row1 = tmp_row;
  1105.       col1 = tmp_col;
  1106.       if (tunindex < 1000)
  1107.         {
  1108.           tunstk[tunindex].y = row1;
  1109.           tunstk[tunindex].x = col1;
  1110.           tunindex++;
  1111.         }
  1112.       door_flag = FALSE;
  1113.     }
  1114.       else if (c_ptr->fval == TMP2_WALL)
  1115.     /* do nothing */
  1116.     ;
  1117.       else if (c_ptr->fval == GRANITE_WALL)
  1118.     {
  1119.       row1 = tmp_row;
  1120.       col1 = tmp_col;
  1121.       if (wallindex < 1000)
  1122.         {
  1123.           wallstk[wallindex].y = row1;
  1124.           wallstk[wallindex].x = col1;
  1125.           wallindex++;
  1126.         }
  1127.       /* RW bug fix to allow tunnel between rooms two squares apart */
  1128.       i=row1+row_dir; j=col1+col_dir;
  1129.       /* if just encountered granite wall, and 'next' space also granite
  1130.          wall, just punch through */
  1131.       if (in_bounds(i,j) && cave[i][j].fval==GRANITE_WALL)
  1132.         cave[i][j].fval=NULL_WALL;
  1133.       for (i = row1-1; i <= row1+1; i++)
  1134.         for (j = col1-1; j <= col1+1; j++)
  1135.           if (in_bounds(i, j))
  1136.         {
  1137.           d_ptr = &cave[i][j];
  1138.           /* values 11 and 12 are impossible here, place_streamer
  1139.              is never run before build_tunnel */
  1140.           if (d_ptr->fval == GRANITE_WALL)
  1141.             d_ptr->fval = TMP2_WALL;
  1142.         }
  1143.     }
  1144.       else if (c_ptr->fval == CORR_FLOOR || c_ptr->fval == BLOCKED_FLOOR)
  1145.     {
  1146.       row1 = tmp_row;
  1147.       col1 = tmp_col;
  1148.       if (!door_flag)
  1149.         {
  1150.           if (doorindex < 100)
  1151.         {
  1152.           doorstk[doorindex].y = row1;
  1153.           doorstk[doorindex].x = col1;
  1154.           doorindex++;
  1155.         }
  1156.           door_flag = TRUE;
  1157.         }
  1158.       if (randint(100) > DUN_TUN_CON)
  1159.         {
  1160.           /* make sure that tunnel has gone a reasonable distance
  1161.          before stopping it, this helps prevent isolated rooms */
  1162.           tmp_row = row1 - start_row;
  1163.           if (tmp_row < 0) tmp_row = -tmp_row;
  1164.           tmp_col = col1 - start_col;
  1165.           if (tmp_col < 0) tmp_col = -tmp_col;
  1166.           if (tmp_row > 10 || tmp_col > 10)
  1167.         stop_flag = TRUE;
  1168.         }
  1169.     }
  1170.       else  /* c_ptr->fval != NULL, TMP2, GRANITE, CORR */
  1171.     {
  1172.       row1 = tmp_row;
  1173.       col1 = tmp_col;
  1174.     }
  1175.     }
  1176.   while (((row1 != row2) || (col1 != col2)) && (!stop_flag));
  1177.  
  1178.   tun_ptr = &tunstk[0];
  1179.   for (i = 0; i < tunindex; i++)
  1180.     {
  1181.       d_ptr = &cave[tun_ptr->y][tun_ptr->x];
  1182.       d_ptr->fval  = CORR_FLOOR;
  1183.       tun_ptr++;
  1184.     }
  1185.   for (i = 0; i < wallindex; i++)
  1186.     {
  1187.       c_ptr = &cave[wallstk[i].y][wallstk[i].x];
  1188.       if (c_ptr->fval == TMP2_WALL)
  1189.     {
  1190.       if (randint(100) < DUN_TUN_PEN)
  1191.         place_door(wallstk[i].y, wallstk[i].x);
  1192.       else
  1193.         {
  1194.           /* these have to be doorways to rooms */
  1195.           c_ptr->fval  = CORR_FLOOR;
  1196.         }
  1197.     }
  1198.     }
  1199. }
  1200.  
  1201.  
  1202. static int next_to(y, x)
  1203. register int y, x;
  1204. {
  1205.   register int next;
  1206.  
  1207.   if (next_to_corr(y, x) > 2)
  1208.     if ((cave[y-1][x].fval >= MIN_CAVE_WALL)
  1209.     && (cave[y+1][x].fval >= MIN_CAVE_WALL))
  1210.       next = TRUE;
  1211.     else if ((cave[y][x-1].fval >= MIN_CAVE_WALL)
  1212.          && (cave[y][x+1].fval >= MIN_CAVE_WALL))
  1213.       next = TRUE;
  1214.     else
  1215.       next = FALSE;
  1216.   else
  1217.     next = FALSE;
  1218.   return(next);
  1219. }
  1220.  
  1221. /* Places door at y, x position if at least 2 walls found    */
  1222. static void try_door(y, x)
  1223. register int y, x;
  1224. {
  1225.   if ((cave[y][x].fval == CORR_FLOOR) && (randint(100) > DUN_TUN_JCT)
  1226.       && next_to(y, x))
  1227.     place_door(y, x);
  1228. }
  1229.  
  1230.  
  1231. /* Returns random co-ordinates                -RAK-    */
  1232. static void new_spot(y, x)
  1233. int16 *y, *x;
  1234. {
  1235.   register int i, j;
  1236.   register cave_type *c_ptr;
  1237.  
  1238.   do
  1239.     {
  1240.       i = randint(cur_height - 2);
  1241.       j = randint(cur_width - 2);
  1242.       c_ptr = &cave[i][j];
  1243.     }
  1244.   while (c_ptr->fval >= MIN_CLOSED_SPACE || (c_ptr->cptr != 0)
  1245.      || (c_ptr->tptr != 0));
  1246.   *y = i;
  1247.   *x = j;
  1248. }
  1249.  
  1250.  
  1251. /* Cave logic flow for generation of new dungeon        */
  1252. static void cave_gen()
  1253. {
  1254.   struct spot_type
  1255.     {
  1256.       int endx;
  1257.       int endy;
  1258.     };
  1259.   int room_map[20][20];
  1260.   register int i, j, k;
  1261.   int y1, x1, y2, x2, pick1, pick2, tmp;
  1262.   int row_rooms, col_rooms, alloc_level;
  1263.   int16 yloc[400], xloc[400];
  1264.  
  1265.   row_rooms = 2*(cur_height/SCREEN_HEIGHT);
  1266.   col_rooms = 2*(cur_width /SCREEN_WIDTH);
  1267.   for (i = 0; i < row_rooms; i++)
  1268.     for (j = 0; j < col_rooms; j++)
  1269.       room_map[i][j] = FALSE;
  1270.   k = randnor(DUN_ROO_MEA, 2);
  1271.   for (i = 0; i < k; i++)
  1272.     room_map[randint(row_rooms)-1][randint(col_rooms)-1] = TRUE;
  1273.   k = 0;
  1274.   for (i = 0; i < row_rooms; i++)
  1275.     for (j = 0; j < col_rooms; j++)
  1276.       if (room_map[i][j] == TRUE)
  1277.     {
  1278.       yloc[k] = i * (SCREEN_HEIGHT >> 1) + QUART_HEIGHT;
  1279.       xloc[k] = j * (SCREEN_WIDTH >> 1) + QUART_WIDTH;
  1280.       if (dun_level > randint(DUN_UNUSUAL))
  1281.         {
  1282.           tmp = randint(3);
  1283.           if (tmp == 1)     build_type1(yloc[k], xloc[k]);
  1284.           else if (tmp == 2) build_type2(yloc[k], xloc[k]);
  1285.           else         build_type3(yloc[k], xloc[k]);
  1286.         }
  1287.       else
  1288.         build_room(yloc[k], xloc[k]);
  1289.       k++;
  1290. #ifdef MAC
  1291.       SystemTask ();
  1292. #endif
  1293.     }
  1294.   for (i = 0; i < k; i++)
  1295.     {
  1296.       pick1 = randint(k) - 1;
  1297.       pick2 = randint(k) - 1;
  1298.       y1 = yloc[pick1];
  1299.       x1 = xloc[pick1];
  1300.       yloc[pick1] = yloc[pick2];
  1301.       xloc[pick1] = xloc[pick2];
  1302.       yloc[pick2] = y1;
  1303.       xloc[pick2] = x1;
  1304.       }
  1305.   doorindex = 0;
  1306.   /* move zero entry to k, so that can call build_tunnel all k times */
  1307.   yloc[k] = yloc[0];
  1308.   xloc[k] = xloc[0];
  1309.   for (i = 0; i < k; i++)
  1310.     {
  1311.       y1 = yloc[i];
  1312.       x1 = xloc[i];
  1313.       y2 = yloc[i+1];
  1314.       x2 = xloc[i+1];
  1315.       build_tunnel(y2, x2, y1, x1);
  1316.     }
  1317. #ifdef MAC
  1318.   SystemTask ();
  1319. #endif
  1320.   fill_cave(GRANITE_WALL);
  1321.   for (i = 0; i < DUN_STR_MAG; i++)
  1322.     place_streamer(MAGMA_WALL, DUN_STR_MC);
  1323.   for (i = 0; i < DUN_STR_QUA; i++)
  1324.     place_streamer(QUARTZ_WALL, DUN_STR_QC);
  1325.   place_boundary();
  1326.   /* Place intersection doors    */
  1327.   for (i = 0; i < doorindex; i++)
  1328.     {
  1329.       try_door(doorstk[i].y, doorstk[i].x-1);
  1330.       try_door(doorstk[i].y, doorstk[i].x+1);
  1331.       try_door(doorstk[i].y-1, doorstk[i].x);
  1332.       try_door(doorstk[i].y+1, doorstk[i].x);
  1333.     }
  1334. #ifdef MAC
  1335.   SystemTask ();
  1336. #endif
  1337.   alloc_level = (dun_level/3);
  1338.   if (alloc_level < 2)
  1339.     alloc_level = 2;
  1340.   else if (alloc_level > 10)
  1341.     alloc_level = 10;
  1342.   place_stairs(2, randint(2)+2, 3);
  1343.   place_stairs(1, randint(2), 3);
  1344.   /* Set up the character co-ords, used by alloc_monster, place_win_monster */
  1345.   new_spot(&char_row, &char_col);
  1346.   alloc_monster((randint(8)+MIN_MALLOC_LEVEL+alloc_level), 0, TRUE);
  1347.   alloc_object(set_corr, 3, randint(alloc_level));
  1348.   alloc_object(set_room, 5, randnor(TREAS_ROOM_ALLOC, 3));
  1349.   alloc_object(set_floor, 5, randnor(TREAS_ANY_ALLOC, 3));
  1350.   alloc_object(set_floor, 4, randnor(TREAS_GOLD_ALLOC, 3));
  1351.   alloc_object(set_floor, 1, randint(alloc_level));
  1352.   if (dun_level >= WIN_MON_APPEAR)  place_win_monster();
  1353. }
  1354.  
  1355.  
  1356. /* Builds a store at a row, column coordinate            */
  1357. static void build_store(store_num, y, x)
  1358. int store_num, y, x;
  1359. {
  1360.   int yval, y_height, y_depth;
  1361.   int xval, x_left, x_right;
  1362.   register int i, j;
  1363.   int cur_pos, tmp;
  1364.   register cave_type *c_ptr;
  1365.  
  1366.   yval       = y*10 + 5;
  1367.   xval       = x*16 + 16;
  1368.   y_height = yval - randint(3);
  1369.   y_depth  = yval + randint(4);
  1370.   x_left   = xval - randint(6);
  1371.   x_right  = xval + randint(6);
  1372.   for (i = y_height; i <= y_depth; i++)
  1373.     for (j = x_left; j <= x_right; j++)
  1374.       cave[i][j].fval     = BOUNDARY_WALL;
  1375.   tmp = randint(4);
  1376.   if (tmp < 3)
  1377.     {
  1378.       i = randint(y_depth-y_height) + y_height - 1;
  1379.       if (tmp == 1) j = x_left;
  1380.       else        j = x_right;
  1381.     }
  1382.   else
  1383.     {
  1384.       j = randint(x_right-x_left) + x_left - 1;
  1385.       if (tmp == 3) i = y_depth;
  1386.       else        i = y_height;
  1387.     }
  1388.   c_ptr = &cave[i][j];
  1389.   c_ptr->fval  = CORR_FLOOR;
  1390.   cur_pos = popt();
  1391.   c_ptr->tptr = cur_pos;
  1392.   invcopy(&t_list[cur_pos], OBJ_STORE_DOOR + store_num);
  1393. }
  1394.  
  1395.  
  1396. /* Link all free space in treasure list together        */
  1397. static void tlink()
  1398. {
  1399.   register int i;
  1400.  
  1401.   for (i = 0; i < MAX_TALLOC; i++)
  1402.     invcopy(&t_list[i], OBJ_NOTHING);
  1403.   tcptr = MIN_TRIX;
  1404. }
  1405.  
  1406.  
  1407. /* Link all free space in monster list together            */
  1408. static void mlink()
  1409. {
  1410.   register int i;
  1411.  
  1412.   for (i = 0; i < MAX_MALLOC; i++)
  1413.       m_list[i] = blank_monster;
  1414.   mfptr = MIN_MONIX;
  1415. }
  1416.  
  1417.  
  1418. /* Town logic flow for generation of new town        */
  1419. static void town_gen()
  1420. {
  1421.   register int i, j, l, m;
  1422.   register cave_type *c_ptr;
  1423.   int rooms[6], k;
  1424.  
  1425.   set_seed(town_seed);
  1426.   for (i = 0; i < 6; i++)
  1427.     rooms[i] = i;
  1428.   l = 6;
  1429.   for (i = 0; i < 2; i++)
  1430.     for (j = 0; j < 3; j++)
  1431.       {
  1432.     k = randint(l) - 1;
  1433.     build_store(rooms[k], i, j);
  1434.     for (m = k; m < l-1; m++)
  1435.       rooms[m] = rooms[m+1];
  1436.     l--;
  1437.       }
  1438.   fill_cave(DARK_FLOOR);
  1439.   /* make stairs before reset_seed, so that they don't move around */
  1440.   place_boundary();
  1441.   place_stairs(2, 1, 0);
  1442.   reset_seed();
  1443.   /* Set up the character co-ords, used by alloc_monster below */
  1444.   new_spot(&char_row, &char_col);
  1445.   if (0x1 & (turn / 5000))
  1446.     {        /* Night    */
  1447.       for (i = 0; i < cur_height; i++)
  1448.     {
  1449.       c_ptr = &cave[i][0];
  1450.       for (j = 0; j < cur_width; j++)
  1451.         {
  1452.           if (c_ptr->fval != DARK_FLOOR)
  1453.         c_ptr->pl = TRUE;
  1454.           c_ptr++;
  1455.         }
  1456. #ifdef MAC
  1457.       SystemTask ();
  1458. #endif
  1459.     }
  1460.       alloc_monster(MIN_MALLOC_TN, 3, TRUE);
  1461.     }
  1462.   else
  1463.     {        /* Day    */
  1464.       for (i = 0; i < cur_height; i++)
  1465.     {
  1466.       c_ptr = &cave[i][0];
  1467.       for (j = 0; j < cur_width; j++)
  1468.         {
  1469.           c_ptr->pl = TRUE;
  1470.           c_ptr++;
  1471.         }
  1472. #ifdef MAC
  1473.       SystemTask ();
  1474. #endif
  1475.     }
  1476.       alloc_monster(MIN_MALLOC_TD, 3, TRUE);
  1477.     }
  1478.   store_maint();
  1479. }
  1480.  
  1481.  
  1482. /* Generates a random dungeon level            -RAK-    */
  1483. void generate_cave()
  1484. {
  1485.   panel_row_min    = 0;
  1486.   panel_row_max    = 0;
  1487.   panel_col_min    = 0;
  1488.   panel_col_max    = 0;
  1489.   char_row = -1;
  1490.   char_col = -1;
  1491.  
  1492. #ifdef MAC
  1493.   macbeginwait ();
  1494. #endif
  1495.  
  1496.   tlink();
  1497.   mlink();
  1498.   blank_cave();
  1499.  
  1500.   if (dun_level == 0)
  1501.     {
  1502.       cur_height = SCREEN_HEIGHT;
  1503.       cur_width     = SCREEN_WIDTH;
  1504.       max_panel_rows = (cur_height/SCREEN_HEIGHT)*2 - 2;
  1505.       max_panel_cols = (cur_width /SCREEN_WIDTH )*2 - 2;
  1506.       panel_row = max_panel_rows;
  1507.       panel_col = max_panel_cols;
  1508.       town_gen();
  1509.     }
  1510.   else
  1511.     {
  1512.       cur_height = MAX_HEIGHT;
  1513.       cur_width     = MAX_WIDTH;
  1514.       max_panel_rows = (cur_height/SCREEN_HEIGHT)*2 - 2;
  1515.       max_panel_cols = (cur_width /SCREEN_WIDTH )*2 - 2;
  1516.       panel_row = max_panel_rows;
  1517.       panel_col = max_panel_cols;
  1518.       cave_gen();
  1519.     }
  1520. #ifdef MAC
  1521.   macendwait ();
  1522. #endif
  1523. }
  1524.